package com.wayz.service;

import com.wayz.constants.PageVo;
import com.wayz.constants.ViewKeyValue;
import com.wayz.entity.dto.agent.AgentDto;
import com.wayz.entity.pojo.agent.DAgentCompany;
import com.wayz.entity.pojo.agent.DAgentCompanyRelation;
import com.wayz.entity.redis.agent.RAgentCompany;
import com.wayz.entity.vo.agent.AgentCompanyVo;
import com.wayz.entity.vo.agent.AgentOEMVo;
import com.wayz.exception.WayzException;
import com.wayz.mapper.DAgentCompanyDAO;
import com.wayz.mapper.DAgentCompanyRelationDAO;
import com.wayz.redis.BeanIdKeyEnum;
import com.wayz.redis.RedisUtils;
import com.wayz.util.TimeHelper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 代理商服务实现类
 *
 * @author mike.ma@wayz.ai
 */
@Service(version = "1.0.0", protocol = "dubbo")
@RefreshScope
public class AgentServiceImpl implements AgentService {

    /**
     * Redis工具类
     */
    @Resource(name = "redisUtils")
    private RedisUtils redisUtils;
    /**
     * 代理商DAO
     */
    @Resource(name = "dAgentCompanyDAO")
    private DAgentCompanyDAO dAgentCompanyDAO;
    /**
     * 代理商关联DAO
     */
    @Resource(name = "dAgentCompanyRelationDAO")
    private DAgentCompanyRelationDAO dAgentCompanyRelationDAO;
    /**
     * 代理商用户服务
     */
    @Resource(name = "agentUserService")
    private AgentUserService agentUserService;

    /**
     * 代理商列表id name
     *
     * @return
     */
    @Override
    public List<ViewKeyValue> queryAgentCompanyView() throws WayzException {
        return dAgentCompanyRelationDAO.queryAgentCompanyView();
    }

    /**
     * 代理商列表
     *
     * @param myId       我的ID
     * @param name       代理商名称
     * @param phone      手机号
     * @param status     状态
     * @param startIndex 开始角标
     * @param pageSize   每页大小
     * @return
     */
    @Override
    public PageVo<AgentCompanyVo> queryAgentCompany(Long myId, String name, String phone, Short status, Long provinceId,
                                                    Long cityId, Long categoryId, Integer startIndex, Integer pageSize) throws WayzException {

        PageVo<AgentCompanyVo> result = new PageVo<AgentCompanyVo>();
        Integer count = dAgentCompanyDAO.countAgentCompany(name, phone, status, provinceId, cityId, categoryId);
        if (count <= 0) {
            return result;
        }
        List<DAgentCompany> dAgentCompanyList = dAgentCompanyDAO.queryAgentCompany(name, phone, status, provinceId,
                cityId, categoryId, startIndex, pageSize);
        List<AgentCompanyVo> agentCompanyList = new ArrayList<>();
        for (DAgentCompany dAgentCompany : dAgentCompanyList) {
            AgentCompanyVo agentCompany = new AgentCompanyVo();
            BeanUtils.copyProperties(dAgentCompany, agentCompany);
            agentCompany.setCreatedTime(TimeHelper.getTimestamp(dAgentCompany.getCreatedTime()));
            agentCompanyList.add(agentCompany);
        }
        result.setList(agentCompanyList);
        result.setTotalCount(count);
        return result;
    }

    /**
     * 获取代理商详情
     *
     * @param myId 我的标识
     * @param id   代理商标识
     * @return
     * @throws WayzException
     */
    @Override
    public AgentCompanyVo getAgentCompany(Long myId, Long id) throws WayzException {
        DAgentCompany dAgentCompany = dAgentCompanyDAO.get(id);
        if (dAgentCompany == null) {
            throw new WayzException("无代理商信息，请联系管理员");
        }
        AgentCompanyVo agentCompany = new AgentCompanyVo();
        BeanUtils.copyProperties(dAgentCompany, agentCompany);
        agentCompany.setCreatedTime(TimeHelper.getTimestamp(dAgentCompany.getCreatedTime()));
        // agentCompany.setConsumePositionLimit(dAgentCompanyDAO.countPositionLimit(id));
        agentCompany.setConsumePositionLimit(0);
        return agentCompany;
    }

    /**
     * 创建代理商
     *
     * @param myId 我的ID
     * @param dto  创建实体类
     * @throws WayzException
     */
    @Override
    public void createAgentCompany(Long myId, AgentDto dto) throws WayzException {
        // 获取代理商编号
        Long agentId = redisUtils.incrBy(BeanIdKeyEnum.PROXY_SAAS.getKey(), RedisUtils.STEP_SIZE);
        // 初始化代理商管理员账号
        this.initUser(myId, agentId, dto);
        // 写入mysql数据库
        DAgentCompany agentCompany = this.createAgentCompany(myId, agentId, dto);
        // 写入缓存
        this.cacheAgentCompany(agentId, agentCompany);

    }

    /**
     * 写入缓存
     *
     * @param agentId
     * @param dAgentCompanyCreate
     */
    private void cacheAgentCompany(Long agentId, DAgentCompany dAgentCompanyCreate) throws WayzException {
        RAgentCompany rAgentCompany = new RAgentCompany();
        BeanUtils.copyProperties(dAgentCompanyCreate, rAgentCompany);
        rAgentCompany.setAgentId(agentId);
        rAgentCompany.setSurplusPositionLimit(dAgentCompanyCreate.getPositionLimit());
        redisUtils.hPutBeanAsHash(RAgentCompany.getKey(agentId), rAgentCompany);
    }

    /**
     * 写入mysql数据库
     *
     * @param myId
     * @param agentId
     * @param dto
     * @return
     * @throws WayzException
     */
    private DAgentCompany createAgentCompany(Long myId, Long agentId, AgentDto dto) throws WayzException {
        Boolean exist = dAgentCompanyDAO.existByName(dto.getName());
        if (exist) {
            throw new WayzException("代理商名称已存在");
        }
        exist = dAgentCompanyDAO.existByPhone(dto.getTelephone());
        if (exist) {
            throw new WayzException("代理商手机号已存在");
        }
        // 创建代理商公司
        DAgentCompany create = new DAgentCompany();
        BeanUtils.copyProperties(dto, create);
        create.setId(agentId);
        create.setCreatorId(myId);
        dAgentCompanyDAO.create(agentId, create);
        return create;
    }

    /**
     * 初写入mysql数据库
     *
     * @param myId
     * @param dto
     * @param agentId
     * @return
     * @throws WayzException
     */
    private Long initUser(Long myId, Long agentId, AgentDto dto) throws WayzException {
        Long roleId = dAgentCompanyDAO.getAgentRoleId();
        return agentUserService.createUser(myId, agentId, roleId, dto);
    }


    /**
     * 修改代理商
     *
     * @param myId 我的ID
     * @param dto  实体类
     * @throws WayzException
     */
    @Override
    public void modifyAgentCompany(Long myId, AgentDto dto) throws WayzException {
        // Redis维护
        RAgentCompany rAgentCompany = this.checkParam(dto);
        // 更新数据库
        updateCompany(dto);
        // 更新Redis
        redisUtils.hPutBeanAsHash(RAgentCompany.getKey(dto.getId()), rAgentCompany);
    }

    /**
     * 校验参数并维护缓存
     *
     * @param dto
     */
    private RAgentCompany checkParam(AgentDto dto) throws WayzException {
        Long id = dto.getId();
        RAgentCompany rAgentCompany = redisUtils.hGetAllAsBean(RAgentCompany.getKey(id), RAgentCompany.class);
        rAgentCompany.setAgentId(id);
        // 代理商名称
        String name = dto.getName();
        if (!rAgentCompany.getName().equals(name)) {
            Boolean exist = dAgentCompanyDAO.existByName(dto.getName());
            if (exist) {
                throw new WayzException("代理商名称已存在");
            }
            rAgentCompany.setName(name);
        }

        // 如果修改了手机号
        String telephone = dto.getTelephone();
        if (!rAgentCompany.getTelephone().equals(telephone)) {
            Boolean exist = dAgentCompanyDAO.existByPhone(dto.getTelephone());
            if (exist) {
                throw new WayzException("代理商手机号已存在");
            }
            rAgentCompany.setTelephone(telephone);
        }
        rAgentCompany.setContacts(dto.getContacts());
        rAgentCompany.setCategoryId(dto.getCategoryId());
        rAgentCompany.setCityId(dto.getCityId());
        return rAgentCompany;
    }

    /**
     * 更新数据库
     *
     * @param dto
     * @throws WayzException
     */
    private void updateCompany(AgentDto dto) throws WayzException {
        // 修改公司
        DAgentCompany modify = new DAgentCompany();
        BeanUtils.copyProperties(dto, modify);
        dAgentCompanyDAO.modify(modify);
    }

    /**
     * 修改代理商状态
     *
     * @param id     代理商ID
     * @param status 代理商状态(1:启用 2:禁用;)
     * @return
     */
    @Override
    public Integer modifyAgentStatus(Long id, Short status) throws WayzException {
        Integer count = dAgentCompanyDAO.updateAgentStatus(id, status);
        redisUtils.hPut(RAgentCompany.getKey(id), RAgentCompany.STATUS, status.toString());
        return count;
    }

	/**
     * 获取代理商OEM
     *
     * @param myId
     * @param id   代理商ID
     * @return
     * @throws WayzException
     */
    @Override
    public AgentOEMVo getAgentOEM(Long myId, Long id) throws WayzException {
        DAgentCompany dAgentCompany = dAgentCompanyDAO.get(id);
		AgentOEMVo agentOEM = new AgentOEMVo();
        BeanUtils.copyProperties(dAgentCompany, agentOEM);
        return agentOEM;
    }

    /**
     * OEM配置
     *
     * @param myId
     * @param id           代理商ID
     * @param logo         OEM logo
     * @param domain       OEM 域名
     * @param websiteTitle OEM 名称
     * @throws WayzException
     */
    @Override
    public void createAgentOEM(Long myId, Long id, String logo, String domain, String websiteTitle)
            throws WayzException {
        dAgentCompanyDAO.updateAgentOEM(id, logo, domain, websiteTitle);
        RAgentCompany rAgentCompany = redisUtils.hGetAllAsBean(RAgentCompany.getKey(id), RAgentCompany.class);
        rAgentCompany.setLogo(logo);
        rAgentCompany.setDomain(domain);
        rAgentCompany.setWebsiteTitle(websiteTitle);
        redisUtils.hPutBeanAsHash(RAgentCompany.getKey(id), rAgentCompany);
    }

    /**
     * 创建代理商和公司关系
     *
     * @param companyId 公司ID
     * @param agentId   代理商ID
     * @param isLogin   是否一键登录
     * @throws WayzException
     */
    @Override
    public void createAgentRelation(Long companyId, Long agentId, Boolean isLogin) throws WayzException {
        DAgentCompanyRelation create = new DAgentCompanyRelation();
        create.setCompanyId(companyId);
        create.setAgentId(agentId);
        create.setIsLogin(isLogin);
        dAgentCompanyRelationDAO.create(create);
    }

    /**
     * 删除代理商和公司关系
     *
     * @param companyId 公司ID
     * @throws WayzException
     */
    @Override
    public void deleteAgentRelation(Long companyId) throws WayzException {
        dAgentCompanyRelationDAO.delete(companyId);
    }

    /**
     * 更新代理商和公司关系
     *
     * @param companyId 公司ID
     * @param agentId   代理商ID
     * @param isLogin   是否一键登录
     */
    @Override
    public void updateAgentRelation(Long companyId, Long agentId, Boolean isLogin) throws WayzException {
        dAgentCompanyRelationDAO.delete(companyId);
        this.createAgentRelation(companyId, agentId, isLogin);
    }
}
